#include <iostream>
#include <pthread.h>

//内存分配器
template<typename T>
struct Allocator 
{
	T *allocate(size_t size)  //内存开辟
	{
		return (T*)malloc(sizeof(T)*size);
	}

	void deallocate(void *p)  //内存释放
	{
		free(p);
	}

	void construct(T *p, const T &val)  //构造对象
	{
		new (p) T(val);   //定位new
	}

	void destroy(T *p)  //对象析构
	{
		p->~T();         //~T() T类型的析构函数
	}
};

template <typename T,typename Alloc=Allocator<T>>
class lvector
{
	public:
		lvector(int size = 10 , const Alloc &alloc = Allocator<T>())
			:allocator_(alloc)
		{
			first_ = allocator_.allocate(size);
			last_ = first_;
			end_ = first_ + size;

		}

		~lvector()
		{
			for(T *p = first_;p != last_; ++p)
			{
				allocator_.destroy(p);
			}
			allocator_.deallocate(first_);
			first_ = last_ = end_ =nullptr;
		}

		lvector(const lvector<T> &rhs)
		{
			int size = rhs.end_-rhs.first_;
			//first_ = new T[size];
			first_ = allocator_.allocate(size);
			int len = rhs.last_ - rhs.first_;
			for(int i = 0; i< len; ++i)
			{
				allocator_.construct(first_+i,rhs.first_[i]);
			}
			last_ = first_ + len;
			end_ = first_ + size;
		}

		lvector<T>& operator = (const lvector<T>  &rhs)
		{
			if(this == &rhs)
				return *this;
			for(T *p = first_;p != last_; ++p)
			{
				allocator_.destroy(p);
			}
			allocator_.deallocate(first_);
			

			int size = rhs.end_-rhs.first_;
			first_ = allocator_.allocate(size);
			int len = rhs.last_ - rhs.first_;
			for(int i = 0; i< len; ++i)
			{
				allocator_.construct(first_ + i, rhs.first_[i]);
			}
			last_ = first_ + len;
			end_ = first_ + size;
			return *this;
		}
		void push_back(const T &val)
		{
			if(full())
				expand();
			//*last_++ = val;
			allocator_.construct(last_,val);
			++last_;
			
		}

		void pop_back()
		{
			if(empty())
				return;
			//--last_;
			
			--last_;
			allocator_.destroy(last_);
		}

		T back() const
		{
			return *(last_-1);
		}
		bool full() const{return last_==end_;}
		bool empty() const {return last_==first_;}
		bool size() const {return last_-first_;}
	private:
		T* first_;    //指向数组起始的位置
		T* last_;     //指向数组中有效元素的后继位置
		T* end_;     //指向数组空间的后继位置
		Alloc allocator_;//空间配置器

		void expand()
		{
			int size = end_-first_;
			//T* ptmp = new T[size*2];
			T *ptmp = allocator_.allocate(size*2);

			for(int i=0; i<size; ++i)
			{
				//ptmp[i] = first_[i];
				allocator_.construct(ptmp+i,first_[i]);
				allocator_.destroy(first_+i);
			}
			allocator_.deallocate(first_);
			first_ = ptmp;
			last_ = first_ + size;
			end_ =first_ + size*2;
		}
};

class test 
{
	public:
		test(){std::cout<<"test()"<<std::endl;}
		~test(){std::cout<<"~test()"<<std::endl;}
};
int main()
{
	lvector<test> vec;
	test t1,t2,t3;
	vec.push_back(t1);
	vec.push_back(t2);
	vec.push_back(t3);
	return 0;

}
